package minimips
import (
	    "fmt"
	    "dumpwave"
	    "os"
// 	      "time"
// 	      "log"
)
type DEEX struct {
	op,function,offset uint
	rs,rt int
}
type EXDM struct {
	addr int
	read_write uint
}

const ( 
datainiciatial = "$timescale 1ns $end\n"+
	"$scope module yam $end\n"+

	"$var wire 1 decodeExecuteRA 	01#DecodeExecuteRA $end\n"+
	"$var wire 32 decodeExecute	02#DecodeExecute   $end\n"+
	
	
	"$var wire 1 data_outRA 	03#DataOutRA	$end\n"+
	"$var wire 32 data_out 		04#DataOut	$end\n"+
	
	"$var wire 1 execute_rdRA 	05#ExexuteRDRA 	$end\n"+
	"$var wire 32 execute_rd	06#ExecuteRD	$end\n"+

	"$var wire 1 branch_decisionRA 	07#BranchDecisionRA $end\n"+
	"$var wire 1 branch_decision 	08#BranchDecision 	$end\n"+
	
	"$var wire 1 executeDmemRA	09#ExecuteDmemRA $end\n"+
	"$var wire 32 executeDmem 	10#ExecuteDmem $end\n"+
	
	"$var wire 1 imem_addressRA 	11#ImemAddressRA $end\n"+
	"$var wire 32 imem_address	12#ImemAddress $end\n"+
	
	"$var wire 1 decode_instrRA 	13#DecodeInstrRA $end\n"+
	"$var wire 32 decode_instr	14#DecodeInstr $end\n"+
	
	"$var wire 1 imem_dataRA 	15#ImemDataRA $end\n"+
	"$var wire 32 imem_data		16#ImemData $end\n"+
	
	"$var wire 1 dmem_datainRA 	19#DmemDataInRA $end\n"+
	"$var wire 32 dmem_datain	120#DmemDataIn $end\n"+
	
	"$var wire 1 data_inRA 	17#DataINRA $end\n"+
	"$var wire 32 data_in		18#DataIN $end\n"+
	
		
	
	"$upscope $end\n"+
	"$enddefinitions $end\n"+
	"$dumpvars\n"+
	"bx decodeExecuteRA\n"+
	"bx decodeExecute\n"+
	"bx data_inRA\n"+
	"bx data_in\n "+
	
	"bx data_outRA \n"+
	"bx data_out\n"+
	
	"bx execute_rdRA\n"+
	"bx execute_rd\n"+
	
	"bx branch_decisionRA\n"+
	"bx branch_decision\n"+
	
	"bx executeDmemRA\n"+
	"bx executeDmem\n"+
	
	"bx imem_addressRA\n"+
	"bx imem_address\n"+
	
	"bx decode_instrRA\n"+
	"bx decode_instr\n"+
	
	"bx imem_dataRA\n"+
	"bx imem_data\n"+
	
	"$end\n"
)
	
func Minimips (instructions chan []uint32) {
	decodeExecute			:= make(chan DEEX)
	executeDmem			:= make(chan EXDM)
	imem_address			:= make(chan uint)
	imem_data			:= make(chan uint)
	branch_decision			:= make(chan uint)
	decode_instr			:= make(chan uint)
	execute_rd			:= make(chan int)
	dmem_datain			:= make(chan int)
	dmem_dataout			:= make(chan int)
	end				:= make(chan int)
	//gerar vdc
	dumpwave.IniciaWave(datainiciatial)
	
	//minimips
	fmt.Println("[Mini] Inicializando fetch")
	go fetch(branch_decision, decode_instr, imem_address, imem_data)
	
	fmt.Println("[Mini] Inicializando imem")
	go imem(instructions, imem_address, imem_data)
	
	fmt.Println("[Mini] Inicializando decode")
	go decode(decode_instr, decodeExecute, execute_rd, dmem_datain, dmem_dataout,end)

	fmt.Println("[Mini] Inicializando execute")
	go execute(decodeExecute, execute_rd, executeDmem, branch_decision)

	fmt.Println("[Mini] Inicializando dmem")
	go dmem(executeDmem, dmem_datain, dmem_dataout)

	<-end
	
	fmt.Println("[YAM] HALT")
	os.Exit(0)
}
